package com.codemate.interview.config;

import com.codemate.interview.redis.RedisKeyDeletedEventListener;
import com.codemate.interview.redis.RedisKeyExpiredEventListener;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.RedisSerializer;

/**
 * Redis配置
 *
 * @author hice
 */
@EnableCaching
@Configuration
public class RedisConfig {

    @Bean
    public RedisSerializer<String> redisKeySerializer() {
        return RedisSerializer.string();
    }

    @Bean
    public RedisSerializer<Object> redisValueSerializer() {
        return RedisSerializer.json();
    }

    @Bean
    @ConditionalOnBean(RedisConnectionFactory.class)
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.setDefaultSerializer(redisValueSerializer());
        redisTemplate.setKeySerializer(redisKeySerializer());
        redisTemplate.setHashKeySerializer(redisKeySerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    @ConditionalOnBean(RedisConnectionFactory.class)
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory factory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(factory);
        return container;
    }

    @Bean
    @ConditionalOnBean({RedisConnectionFactory.class, RedisMessageListenerContainer.class})
    public RedisKeyExpiredEventListener redisKeyExpiredEventListener(RedisConnectionFactory factory) {
        return new RedisKeyExpiredEventListener(redisMessageListenerContainer(factory));
    }

    @Bean
    @ConditionalOnBean({RedisConnectionFactory.class, RedisMessageListenerContainer.class})
    public RedisKeyDeletedEventListener redisKeyDeletedEventListener(RedisConnectionFactory factory) {
        return new RedisKeyDeletedEventListener(redisMessageListenerContainer(factory));
    }

}
